# -*- coding:utf-8 -*-
# @Time : 21-8-3 下午2:43 
# @Author : zdy
# @File : Format.py
# desc:
from importQT import *
from Class.VoltSignal import dataBase
import pickle
import os

class DelegateResult(QStyledItemDelegate):
    def __init__(self, parent, resultList=dataBase.colresultNum, areaList= dataBase.colareaNum,
                  colorList=None, editList=None, showUint = True, weightList = dataBase.colweightNum,):
        '''
        数据显示格式委托
        :param parent:
        :param resultList: 需要设置结果的列，列的小数位数将按照Format.Result
        :param areaList: 需要设置面积的列
        :param colorList: 需要设置颜色的列
        :param editList: 需要设置编辑效果的列
        '''
        super().__init__(parent)
        self.resultList = resultList
        self.areaList = areaList
        self.colorList = colorList
        self.editList = editList
        self.weightList = weightList
        self.showUint = showUint

    def paint(self, painter, option, index):
        col = index.column()
        if col in self.resultList:
            rect = option.rect
            value = index.data(Qt.DisplayRole)
            text = None
            if value == None:
                text = "***"
            else:
                text = Format.result(value, self.showUint)
            # painter.drawRect(option.rect)
            painter.save()  # 保存painter,以防后续修改
            itemOption = QStyleOptionViewItem(option)
            if itemOption.state & QStyle.State_Selected:
                pen = painter.pen()
                pen.setColor(QColor("white"))
                painter.setPen(pen)
            # if self.colorList is not  None and (col in self.colorList):
            #     pen = painter.pen()
            #     pen.setColor(QColor(0, 255, 0))
            #     painter.setPen(pen)
            try:
                painter.drawText(rect, Qt.AlignVCenter | Qt.AlignHCenter, text)
            except Exception as ex:
                pass
            painter.restore()
        elif self.areaList is not None and (col in self.areaList):
            rect = option.rect
            value = index.data(Qt.DisplayRole)
            text = None
            if value == None:
                text = "***"
            else:
                text = Format.area(value)
            painter.save()  # 保存painter,以防后续修改
            itemOption = QStyleOptionViewItem(option)
            if itemOption.state & QStyle.State_Selected:
                pen = painter.pen()
                pen.setColor(QColor("white"))
                painter.setPen(pen)
            painter.drawText(rect, Qt.AlignVCenter | Qt.AlignHCenter, text)
            painter.restore()
        elif self.weightList is not None and (col in self.weightList):
            rect = option.rect
            value = index.data(Qt.DisplayRole)
            text = None
            if value == None:
                text = "***"
            else:
                text = Format.weight(value)
            painter.save()  # 保存painter,以防后续修改
            itemOption = QStyleOptionViewItem(option)
            if itemOption.state & QStyle.State_Selected:
                pen = painter.pen()
                pen.setColor(QColor("white"))
                painter.setPen(pen)
            painter.drawText(rect, Qt.AlignVCenter | Qt.AlignHCenter, text)
            painter.restore()
        else:
            #设置选中时的字体颜色
            # itemOption = QStyleOptionViewItem(option)
            # itemOption.displayAlignment = Qt.AlignCenter
            # if itemOption.state & QStyle.State_Selected:
            #     itemOption.font.setBold(True)
            # itemOption.palette.setColor(QPalette.HighlightedText, QColor(0, 255, 0))
            return QStyledItemDelegate.paint(self, painter, option, index)

    # 创建编辑器
    def createEditor(self, parent, option, index):
        if self.editList is not None and (index.column() in self.editList):
            editor = QDoubleSpinBox(parent)
            editor.setDecimals(6)
            editor.setRange(0, 100)
            editor.setSingleStep(0.000001)
            return editor
        else:
            return QStyledItemDelegate.createEditor(self, parent, option, index)

    # 设置编辑器的位置
    def updateEditorGeometry(self, edit, option, index):
        if index.column() in self.editList:
            edit.setGeometry(option.rect)
        else:
            return QStyledItemDelegate.updateEditorGeometry(self, edit, option, index)

    # 设置数据到模型
    def setModelData(self, edit, model, index):
        if index.column() in self.editList:
            model.setData(index, edit.value(), Qt.EditRole)
            pass
        else:
            return QStyledItemDelegate.setModelData(self, edit, model, index)

    # 设置数据到视图
    def setEditorData(self, edit, index):
        if index.column() in self.editList:
            value = float(index.data(Qt.EditRole))
            edit.setValue(value)
        else:
            return QStyledItemDelegate.setEditorData(self, edit, index)

class Format(object):
    decimals = 6
    def __init__(self):
        pass

    @staticmethod
    def weight(value):
        str = '%.4f' % value
        return str

    @staticmethod
    def result(value, showUnit=True):
        """格式化数据显示，返回字符串"""
        if value == None or value == -999:
            return "***"
        try:
            x = float(value)
        except Exception as ex:
            return value
        if value < 0:
            value = 0.0
        if value >100:
            value = 100.0
        s = '%.' + str(Format.decimals) + "f"
        s1 = s % value
        if showUnit:
            s1 += "%"
        return s1

    @staticmethod
    def percent(value, showUnit=True):
        if isinstance(value, float):
            s = '%.2f' % value
            if showUnit:
                s += "%"
            return s
        else:
            return value

    @staticmethod
    def area(value):
        """格式化数据显示，返回字符串"""
        if value is None or value == -999:
            return "***"
        str = '%.4f' % value
        return str

    def value(v):
        """格式化数据显示，返回字符串"""
        if v is None:
            return "***"
        str = '%.4f' % v
        return str

    @staticmethod
    def value6decim(v):
        if v is None:
            return "***"
        str = '%.6f' % v
        return str

class Serialization(object):
    def __init__(self):
        pass

    @staticmethod
    def serializeToFile(filepath, type):
        """将方法二进制序列化到文件"""
        # wb:以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件，并从开头开始编辑，即原有内容会被删除。如果该文件不存在，创建新文件。
        with open(filepath, 'wb') as file:
            pickle.dump(type, file)

    @staticmethod
    def deserialize(filepath):
        """反序列化到对象，若异常，返回None"""
        # rb:以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。
        type = None
        if os.path.exists(filepath):
            with open(filepath, 'rb') as file:
                type = pickle.load(file)
        return type

def setupTable(tv: QTableView, model, colHiddens):
    tv.setModel(model)
    # 设置行选择
    tv.setSelectionBehavior(QAbstractItemView.SelectRows)
    tv.setSelectionMode(QAbstractItemView.ExtendedSelection)  # 设置可选多个
    # self.tableView.resizeColumnsToContents()    #列宽自适应
    tv.setEditTriggers(QAbstractItemView.NoEditTriggers)
    tv.setShowGrid(True)
    tv.setGridStyle(Qt.SolidLine)
    tv.setContextMenuPolicy(Qt.CustomContextMenu)
    tv.setItemDelegate(DelegateResult(tv))
    tv.setColumnWidth(0, 150)
    tv.setColumnWidth(1, 150)
    colHeaderView = tv.horizontalHeader()
    colHeaderView.setSectionsMovable(True)
    #TODO
    for col in colHiddens:
        tv.setColumnHidden(col, True)

